import {
    request,
    AbstractDiscoverCrawler,
    DiscoverCrawlerTest,
    DiscoverBook,
    PageResult,
    RequestOptions,
    RequestType,
    RequestInputType,
    DiscoverSource,
    GenderEnum,
    FilterOption,
    FilterCategory,
    FilterParameter,
    FilterCategoryType,
    getCookies,
} from "../../common/common_node.js";


class DiscoverCrawler extends AbstractDiscoverCrawler {

    getRankBaseUrl(gender) {
        return `${this.source.getPortalUrl(gender)}/all`;
    }

    cookies = null;

    /**
     * 起点发送请求
     * @param {String} url
     * @return {RequestResponse}
     */
    async qdRequest(url) {
        const cookieUrl = this.source.getPortalUrl(GenderEnum.female);
        this.cookies ??= await getCookies(cookieUrl);
        let res = await request(url, new RequestOptions({
            headers: {
                "Cookie": this.cookies
            }
        }));
        const $ = await res.doc();
        if ($('script').length > 5) {
            return res;
        }
        this.cookies = await (await request(cookieUrl, new RequestOptions({
            type: RequestType.webView,
            inputType: RequestInputType.cookies,
            delayedGetContent: 1000,
        }))).cookies();
        console.log("从App中获取Cookies22", url, this.cookies);

        return request(url, new RequestOptions({
            headers: {
                "Cookie": this.cookies
            }
        }));
    }

    async filterCategoryList(gender) {

        const url = this.getRankBaseUrl(gender);
        const $ = await (await this.qdRequest(url, this.options)).doc();

        function liToItemList(dataItem, type) {
            const lis = dataItem.find(`[type=${type}] li`);
            const optionList = [];
            lis.each(function (i, e) {
                const li = $(e);
                const name = li.text();
                const value = li.attr("data-id");
                optionList.push(new FilterOption({key: value, name, value}));
            });
            return optionList;
        }


        const dataItemCode = gender === GenderEnum.female ? 1 : 2;
        const dataItem = $(`[data-item='${dataItemCode}']`)

        return [
            new FilterCategory({key: 'action', name: '状态', options: liToItemList(dataItem, "action")}),
            new FilterCategory({key: 'chanId', name: '分类', options: liToItemList(dataItem, "category")}),
            new FilterCategory({key: 'size', name: '字数', options: liToItemList(dataItem, "size")}),
            new FilterCategory({
                key: 'orderId', name: '排序', options: [
                    new FilterOption({key: "0", name: "人气排序", value: "0"}),
                    new FilterOption({key: "11", name: "总收藏", value: "11"}),
                    new FilterOption({key: "3", name: "总字数", value: "3"}),
                    new FilterOption({key: "9", name: "周推荐票", value: "9"}),
                    new FilterOption({key: "10", name: "月推荐票", value: "10"}),
                    new FilterOption({key: "2", name: "总推荐票", value: "2"}),
                    // new FilterOption({ key: "1", name: "周点击", value: "1" }),
                    // new FilterOption({ key: "7", name: "月点击", value: "7" }),
                    // new FilterOption({ key: "8", name: "总点击", value: "8" }),

                ]
            }),
        ];
    }

    async bookPage(pageNum, gender, filterParameterList) {
        /**
         *
         * @param {Object.<String,String>} filterParams
         * @param {FilterParameter} filterParameter
         */
        function disposeParameter(filterParams, filterParameter) {
            if (filterParameter.type === FilterCategoryType.options) {
                filterParams[filterParameter.key] = filterParameter.optionsValue;
            } else if (filterParameter.type === FilterCategoryType.all) {
                filterParams[filterParameter.key] = filterParameter.optionsValue;
                disposeParameter(filterParams, filterParameter.subCategoriesValue);
            }
        }

        const filterParams = {};
        for (const filterParameter of filterParameterList) {
            disposeParameter(filterParams, filterParameter);
        }

        const pathParams = {};
        if (pageNum > 1) {
            pathParams['pageNum'] = pageNum;
        }

        for (let key in filterParams) {
            if (Number.parseInt(filterParams[key]) === -1) {
                continue;
            }
            pathParams[key] = filterParams[key];
        }

        let url = this.getRankBaseUrl(gender);

        if (Object.keys(pathParams).length) {
            const paramList = [];
            for (const [key, value] of Object.entries(pathParams)) {
                paramList.push(`${key}${value}`);
            }
            url = `${url}/${paramList.join('-')}/`;
        }

        const $ = await (await this.qdRequest(url, this.options)).doc();
        const bookArr = [];
        // 请帮我把下面的drat代码转为js代码，doc对应 $ ,bookList对应 bookArr
        const lis = $(".all-img-list li");
        lis.each((i, e) => {
            const li = $(e);
            const bookInfo = li.find(".book-mid-info").first();
            const name = bookInfo.find("a").first().text();
            const intro = bookInfo.find(".intro").text();
            const coverUrl = "https:" + li.find(".book-img-box img").attr("src");
            const authorStr = bookInfo.find(".author").text().trim();
            const arr = authorStr.split("|");
            const author = arr[0];
            const type = arr.length > 1 ? arr[1] : "";
            const status = arr.length > 2 ? arr[2] : "";
            bookArr.push(new DiscoverBook({
                name,
                author,
                intro,
                coverUrl,
                type,
                status
            }));
        });
        return new PageResult({
            pageNum: pageNum,
            pages: Number.parseInt($('.lbf-pagination .lbf-pagination-item [data-page]').last().attr('data-page')),
            list: bookArr
        });
    }

    async hotKeywordList(gender) {
        const url = this.source.getPortalUrl(gender);
        const $ = await (await this.qdRequest(url, this.options)).doc();

        const hotSearchSet = new Set();
        $('a[data-eid="qd_A117"]').each((index, element) => {
            const keyword = $(element).text().trim();
            if (keyword) {
                hotSearchSet.add(keyword);
            }
        });
        return Array.from(hotSearchSet);
    }
}

const source = {
    "id": "freebook/qidian",
    "name": "起点",
    "active": true,
    "portalUrl": "https://www.qidian.com | https://www.qdmm.com",
    "description": "起点中文网",
    "pageTurningMode": "scroll",
    "enableGenderFilter": true,
    "enableDiscover": true,
    "enableHotKeyword": true
};

await new DiscoverCrawlerTest(new DiscoverCrawler(DiscoverSource.createTestDiscoverSource(source))).run();
